<?php
namespace Buu\Modules\ConfManager\Controllers;

use App\Http\Controllers\Controller;
use App\Pockets\GridDataModel as pGridDataModel;
use Doraemon\service\ConfProfile\ConfProfileModule;
use Doraemon\tools\Curl;
use Doraemon\tools\HhzEnv;
use Encore\Admin\Facades\Admin;
use Encore\Admin\Grid;
use Encore\Admin\Layout\Content;
use Illuminate\Http\Request;
use Encore\Admin\Widgets\Tab;
use Encore\Admin\Widgets\Form;
use Illuminate\Support\MessageBag;
use Encore\Admin\Layout\Row;
use Encore\Admin\Widgets\Box;
use Symfony\Component\Yaml\Yaml;
use Doraemon\service\ConfManagerChecker;
use Doraemon\model\ConfManager\ConfManagerLogMysql;
use Doraemon\model\ConfManager\ConfManagerMysql;
use Doraemon\model\ConfManager\ConfManagerMetaMysql;
use Doraemon\tools\ImgUrl;

/**
 * @todo 删除
 */
class ConfManagerController extends Controller
{
    private $metaconf;
    private $metaconf_json;

    //全局通用，读取配置信息并检测当前操作人是否有权限
    private function _read_metaconf_check_permission($project_code){
        if(empty($project_code)){
            die("project_code 为空");
        }
        $this->metaconf = ConfManagerMetaMysql::read_metaconf($project_code);
        $this->metaconf_json = Yaml::parse($this->metaconf['metaconf']);

        if(Admin::user()->isAdministrator() || in_array(Admin::user()->username , $this->metaconf_json['managers'])){
            return true;
        }else{
            die('无权限');
        }
    }

    //首页
    public function index(Content $content, Request $request)
    {
        $pageSize = $request->input('per_page', 20);
        $page = $request->input('page', 1);
        $tab = new Tab();
        $tab->add('配置列表', $this->_index_projectList($page, $pageSize), true);
        $tab->add('增加元配置', $this->_index_createConf());
        $tab->add('视频教学', '
      <h2><a href="https://confluence.haohaozhu.me/pages/viewpage.action?pageId=40730924" target="_blank">点此查看文档及发表你的意见</a></h2>
              <video controls="controls" >
  <source src="https://hhc-test.oss-cn-beijing.aliyuncs.com/conf_manager.mp4" type="video/mp4" />
</video>
');
        $content->row($tab);
        return $content
            ->header('配置管理')
            ->breadcrumb(['text' => '配置管理' ]);
    }

    //首页模块，项目列表
    public function _index_projectList($page, $pageSize)
    {
        //调用获取数据的方法
        $infos = ConfManagerMetaMysql::getDataListByCondition(['status' => 1], $page, $pageSize);
        $gridModel = new pGridDataModel($infos["list"], $infos["counts"], ['perPage' => $pageSize]);

        $gridList = Admin::grid($gridModel, function (Grid $grid) use ($gridModel) {
                $grid->paginate($gridModel->getPerPage());
                $grid->disableExport();
                $grid->disableFilter();
                $grid->disableRowSelector();
                $grid->disableCreateButton();

                $grid->column("project_code", 'project_code');
                $grid->column("project_name", '名称');
                $grid->column("created_at", '创建时间')->display(function () {
                    return $this->created_at->format('Y-m-d H:i:s');
                });;
                $grid->actions(function (Grid\Displayers\Actions $actions) {
                    $actions->disableDelete();
                    $actions->disableEdit();
                    $actions->append('<a href="/admin/confManager/'.$actions->row['project_code'].'/1/edit_conf" class="fa fa-edit">编辑</a>');
                    $actions->append('<a href="/admin/confManager/edit_metaconf/'.$actions->row['project_code'].'" class="fa fa-edit">编辑元配置</a>');

                });
            });

        return $gridList->render();
    }

    //首页模块，新建项目表单
    public function _index_createConf(){
        $form = new Form();
        $form->textarea('metaconf' , '元配置')->rows(30);
        $form->textarea('op_log' , '变更日志')->rows(3)->placeholder('为什么要进行本次变更？')->required();
        $form->action('/admin/confManager/save_metaconf');
        return $form->render();
    }

    //元配置编辑页
    public function edit_metaconf(Content $content, Request $request , $project_code){
        if($project_code){
            $this->_read_metaconf_check_permission($project_code);
        }
        
        $form = new Form($this->metaconf);
        $form->textarea('metaconf' , '元配置')->help("配置检查")->rows(30);
        $form->divider();
        $form->textarea('op_log' , '变更日志')->rows(3)->placeholder('为什么要进行本次变更？')->required();

        if($project_code)
            $form->action('/admin/confManager/save_metaconf/'.$project_code);
        else
            $form->action('/admin/confManager/save_metaconf');
        $box = new Box('编辑元配置', $form->render());
        $content->row($box);

        $script = <<<script
            var metaconf = $("textarea[name='metaconf']")
            isMetaconfEditing = false
            metaconf.bind('input propertychange', function() {
            if (isMetaconfEditing == false){
                isMetaconfEditing = true
                setTimeout(function(){
                    
                    isMetaconfEditing = false
                    $.post("/admin/confManager/check_metaconf/{project_code}",{metaconf:metaconf.val()},function(result){
    if(result == 0){
        metaconf.removeClass("textarea_border_red")
        metaconf.siblings(".help-block").html('<i class="fa fa-info-circle"></i> 正确').css('color','')
    }else{
        metaconf.addClass("textarea_border_red")
        metaconf.siblings(".help-block").html('<i class="fa fa-info-circle"></i> '+result).css('color','red')
    }
  });
                } , 1000)

            }
});

script;
        $script = str_replace('{project_code}', $project_code, $script);
        Admin::script($script);
        Admin::style('.textarea_border_red {border:solid 1px #f00;}');

        return $content
            ->header('元配置管理')
            ->breadcrumb(['text' => '配置管理']);
    }

    //元配置保存接口
    public function save_metaconf(Content $content, Request $request , $project_code = null){
        $log_action = ConfManagerLogMysql::ACT_CREATE_METACONF;
        $old_data = '';
        if($project_code){
            // 获取old_data
            $mysqlData = ConfManagerMetaMysql::getDataByWhere(['value'], [
                'project_code' => $project_code,
            ]);
            $old_data = !empty($mysqlData) ? $mysqlData['value'] : '';
            $log_action = ConfManagerLogMysql::ACT_UPDATE_METACONF;
            $this->_read_metaconf_check_permission($project_code);
        }

        $confChecker = new ConfManagerChecker();

        $metaconf = $request->input('metaconf');
        $op_log = $request->input('op_log');
        $metaconf_json = Yaml::parse($metaconf);

        try {
            $confChecker->check($metaconf_json);    
        } catch (\Exception $e) {

            if($project_code){
                admin_toastr($e->getMessage(), 'error', ['timeOut' => 5000]);
                return redirect('/admin/confManager/edit_metaconf/'.$project_code)->with(compact('failed'));
            }else{
                admin_toastr($e->getMessage(), 'error', ['timeOut' => 5000]);
                return redirect('/admin/confManager/index')->with(compact('failed'));
            }
            
        }
        if($project_code && $project_code != $metaconf_json['project_code']){
            
            admin_toastr('project_code不能变更', 'error', ['timeOut' => 5000]);
            return redirect('/admin/confManager/edit_metaconf/'.$project_code)->with(compact('failed'));
        }
        $project_code_param = $project_code;
        $project_code = $metaconf_json['project_code'];
        if (!$project_code_param){
            // 20220531 新增的时候，需要判断project_code是否已经存在
            $where = [
                'project_code' => $project_code,
            ];
            $mysqlData = ConfManagerMetaMysql::getDataByWhere(['id'], $where);
            if(!empty($mysqlData)) {
                $error = new MessageBag([
                    'title' => '当前' . $project_code . '已经存在！！！'
                ]);
                return back()->with(compact('error'))->withInput();
            }
        }

        $name = $metaconf_json['project_name'];
        // 同时操作mysql
        if (strpos($project_code, ":") !== false) {
            $projectTypeArr = explode(":", $project_code);
        } else {
            $projectTypeArr = explode("_", $project_code);
        }
        $data = [
            'project_type' => $projectTypeArr[0],
            'project_name' => $name,
            'value' => $metaconf,
            'update_username' => Admin::user()->username,
            'updated_at' => date('Y-m-d H:i:s', time()),
            'status' => 1,
        ];
        $dataWhere = [
            'project_code' => $project_code,
        ];
        $updateMysql = ConfManagerMetaMysql::updateData(array_merge($data, $dataWhere), $dataWhere);
        if ($updateMysql == 0) {
            throw new \Exception("更新mysql配置失败", 1);
        }

        //记录变更日志
        ConfManagerLogMysql::insertData([
            'admin_id' => Admin::user()->id,
            'op_action' => $log_action,
            'project_code' => $project_code,
            'version_id' => 1,
            'old_data' => $old_data,
            'new_data' => $metaconf,
            'op_log' => $op_log
        ]);


        admin_toastr('保存成功', 'success', ['timeOut' => 5000]);
        return redirect('/admin/confManager/index/')->with(compact('success'));
    }

    //创建版本分群页面
    public function create_version(Content $content, Request $request , $project_code){
        $this->_read_metaconf_check_permission($project_code);

        $content->row(function(Row $row){
            $row->column(10,$this->_create_condition());
            $row->column(2, $this->_edit_version_list());
        });
        return $content
            ->header($this->metaconf_json['project_name']);
    }

    //编辑分群表单模块
    private function _create_condition($conf_data = null , $version_id = null){

        $form = new Form($conf_data);
        $version_id = $version_id ? $version_id : time();
        $form->text('version_name' , '分群名称')->required();
        $form->text('version_id' , 'ID')->default($version_id)->readonly()->required();

        $form->confProfile('conf_profile', '配置分群')->generate();
        $form->action('/admin/confManager/'.$this->metaconf_json['project_code'].'/save_version_condition');

        $title = $version_id ? '编辑分群版本': '创建分群版本';
        if($version_id){
            $form->divider();
            $form->textarea('op_log' , '变更日志')->rows(3)->placeholder('为什么要进行本次变更？')->required();
        }
        $box_form = new Box($this->metaconf_json['project_name']." -- ".$title , $form->render());
        return $box_form;
    }

    public function check_metaconf(Content $content, Request $request , $project_code = null){
        if($project_code){
            $this->_read_metaconf_check_permission($project_code);
        }

        $confChecker = new ConfManagerChecker();

        $metaconf = $request->input('metaconf');
        $metaconf_json = Yaml::parse($metaconf);

        try {
            $confChecker->check($metaconf_json);    
        } catch (\Exception $e) {
            die($e->getMessage());
        }
        die(0);
    }

    public function save_version_condition(Content $content, Request $request , $project_code){
        $this->_read_metaconf_check_permission($project_code);

        $version_id = $request->input('version_id');
        $userprofile = $request->input('conf_profile');

        $condition_data = array(
            'version_name' => $request->input('version_name'),
            'condition' => '',
        );
        $op_log = $request->input('op_log');
        $taskRulesOld = ConfProfileModule::getPositionRulesById($version_id);

        try {
            ConfProfileModule::addUserProfile($version_id, $userprofile);
            $taskRules = ConfProfileModule::getPositionRulesById($version_id);
            $condition_data['condition'] = $taskRules;

        } catch (\Exception $e) {
            admin_toastr($e->getMessage(), 'error', ['timeOut' => 6000]);
            return redirect('/admin/confManager/'.$project_code.'/'.$version_id.'/edit_version/')
                ->withInput()->with(compact('failed'));
        }

        if (strpos($project_code, ":") !== false) {
            $projectTypeArr = explode(":", $project_code);
        } else {
            $projectTypeArr = explode("_", $project_code);
        }
        // 修改config_set数据
        ConfManagerMysql::updateData([
            'project_code' => $project_code,
            'project_name' => $this->metaconf_json['project_name'],
            'version_id' => $version_id,
            'project_type' => $projectTypeArr[0],
            'version_name' => $condition_data['version_name'],
            'version_detail' => json_encode($taskRules),
            'update_username' => Admin::user()->username,
            'updated_at' => date('Y-m-d H:i:s', time()),
            'status' => 1,
        ], ['project_code' => $project_code,
            'version_id' => $version_id]
        );

        // 通知conf-go进行同步
        $result = Curl::Request('POST', HhzEnv::configDomain() . 'confNotify');
        if ($result['json']['code'] != 1) {
            throw new \Exception("同步到conf-go失败" . HhzEnv::configDomain(), 1);
        }

        //记录变更日志
        ConfManagerLogMysql::insertData([
            'admin_id' => Admin::user()->id,
            'op_action' => ConfManagerLogMysql::ACT_CREATE_VERSION_INFO,
            'project_code' => $project_code,
            'version_id'=>$version_id,
            'new_data' => json_encode($condition_data),
            'old_data' => json_encode($taskRulesOld),
            'op_log' => $op_log
        ]);

        admin_toastr('保存成功', 'success', ['timeOut' => 5000]);
        return redirect('/admin/confManager/'.$project_code.'/'.$version_id.'/edit_version/')->with(compact('success'));
    }

    //编辑配置数据页面
    public function edit_conf(Content $content, Request $request, $project_code, $version_id){
        $this->_read_metaconf_check_permission($project_code);

        // 20220525改成从mysql读取
        $mysqlData = ConfManagerMysql::getDataByWhere(['value'], [
            'project_code' => $project_code,
            'version_id' => $version_id,
        ]);

        $conf_data = !empty($mysqlData) ? json_decode($mysqlData['value'], true) : [];

        $content->row(function(Row $row) use ($project_code, $conf_data, $version_id){
            $row->column(10,$this->_edit_conf_editor($project_code, $conf_data, $version_id));
            $row->column(2, $this->_edit_version_list());
        });

        return $content
        ->header($this->metaconf_json['project_name']);
    }

    //编辑配置数据表单模块
    private function _edit_conf_editor($project_code, $conf_data = null, $version_id = 1){
        //table控件在没数据的情况下未进行兼容，需要给一个[]为默认值
        foreach ($this->metaconf_json['fields'] as $key => $value) {
            if($value['type'] == 'object_list' && !isset($conf_data[$key])){
                $conf_data[$key] = [];
            }
        }

        $form = new Form($conf_data);
        try {
            $this->_form_fields($form , $this->metaconf_json['fields']);    
        } catch (\Exception $e) {
            die($e->getMessage());
        }
        $form->textarea('op_log' , '变更日志')->rows(3)->placeholder('为什么要进行本次变更？')->required();
        $form->disableReset();

        $script = <<<script
            $(".box-footer .col-md-2").html(' <a id="btn_submit" class="btn btn-warning pull-right">检查数据</a> ');
            $('#btn_submit').click(function(){
                $.post("/admin/confManager/{project_code}/1/check_conf",$("form").serialize(),function(result){
                    if(result == 1){

                        }else{
                            alert(result)
                        }
                });
            });

script;
        $script = str_replace('{project_code}' , $project_code , $script);
        Admin::script($script);

        $form->action('/admin/confManager/'.$this->metaconf_json['project_code']. '/' . $version_id .'/save_conf');

        $box_form = new Box('' , $form->render());
        return $box_form;
    }

    //编辑版本分群信息页面
    public function edit_version(Content $content, Request $request ,$project_code, $version_id){
        $this->_read_metaconf_check_permission($project_code);

        $conf = ConfManagerMysql::getDataByWhere(['version_detail', 'version_name'], [
            'project_code' => $project_code,
            'version_id' => $version_id,
        ]);

        $conf_info = [];
        $conf_info['conf_profile'] = ConfProfileModule::getPositionRulesById($version_id, true);
        $conf_info['version_name'] = $conf['version_name'];

        $content->row(function(Row $row) use ($conf_info , $version_id){
            $row->column(10,$this->_create_condition($conf_info , $version_id));
            $row->column(2, $this->_edit_version_list());
        });
        return $content
            ->header($this->metaconf_json['project_name']);
    }

    //配置管理页，右侧版本列表模块
    private function _edit_version_list(){
        $project_code = $this->metaconf_json['project_code'];

        $html = '<li><a href="/admin/confManager/'.$project_code.'/1/edit_conf">默认版本</a></li>';

        $versions = ConfManagerMysql::getDataByWhereList(['version_name', 'version_id'], [
            'project_code' => $project_code,
            'status' => 1,
        ]);

        foreach ($versions as $row) {
            if ($row['version_id'] == 1) {
                continue;
            }
            $html .= '<li><a href="/admin/confManager/'.$project_code.'/'.$row['version_id'].'/edit_conf">'.$row['version_name'].'</a>'
                .' [<a href="/admin/confManager/'.$project_code.'/'.$row['version_id'].'/edit_version">编辑分群</a>] '
                .' [<a href="/admin/confManager/'.$project_code.'/'.$row['version_id'].'/del_version_confirm">删除</a>] ';
        }
        $html .='<a href="/admin/confManager/'.$project_code.'/create_version" class="btn btn-info btn-block"> 新建分群版本 </a>';


        $box = new Box('版本列表', $html);
        $box_info = new Box($this->metaconf_json['project_name'], $this->metaconf_json['description']);
        return $box_info.$box;
    }

    // meta编辑配置数据表单模块
    private function _form_fields(&$form , $fields , $in_object = false , $key_prefix = ''){

        foreach ($fields as $key => $field) {

            $form_key = $key_prefix.$key;
            switch ($field['type']) {
                case 'bool':
                    $states = [
                        '1'  => ['value' => 1, 'text' => '打开', 'color' => 'success'],
                        '0' => ['value' => 0, 'text' => '关闭', 'color' => 'danger'],
                    ];
                    $bool_input = $form->switch($form_key , $field['name'])->states($states);
                    if(isset($field['description'])){ $bool_input->help($field['description']); }
                    if(isset($field['default'])){ $bool_input->default($field['default']);}
                    break;
                case 'int':

                    $int_input = $form->number($form_key , $field['name'])->required();
                    if(isset($field['description'])){ $int_input->help($field['description']); }
                    if(isset($field['max'])){ $int_input->max($field['max']); }
                    if(isset($field['min'])){ $int_input->min($field['min']); }
                    if(isset($field['default'])){ $int_input->default($field['default']); }
                    break;
                case 'date':
                    $date_input = $form->date($form_key , $field['name']);
                    if(!isset($field['is_null'])){ $date_input->required(); }
                    if(isset($field['default'])){ $date_input->default($field['default']); }
                    break;
                case 'datetime':
                    $datetime_input = $form->datetime($form_key , $field['name']);
                    if(!isset($field['is_null'])){ $datetime_input->required(); }
                    if(isset($field['default'])){ $datetime_input->default($field['default']); }
                    break;
                case 'color':
                    $color_input = $form->color($form_key , $field['name']);
                    if(!isset($field['is_null'])){ $color_input->required(); }
                    if(isset($field['default'])){ $color_input->default($field['default']); }
                    break;
                case 'pic_upload':
                    $upload_input = $form->imgUpload($form_key , $field['name']);
                    if(!isset($field['is_null'])){ $upload_input->required(); }
                    if(isset($field['rules']['min_width'])){ $upload_input->setMinImageWidth($field['rules']['min_width']); }
                    if(isset($field['rules']['max_width'])){ $upload_input->setMaxImageWidth($field['rules']['max_width']); }
                    if(isset($field['rules']['min_height'])){ $upload_input->setMinImageHeight($field['rules']['min_height']); }
                    if(isset($field['rules']['max_height'])){ $upload_input->setMaxImageHeight($field['rules']['max_height']); }
                    break;
                case 'hhzlink':
                    $link_input = $form->multiLinkSelect($form_key , $field['name']);
                    break;
                case 'string':

                    $str_input = $form->text($form_key , $field['name']);
                    if(!isset($field['is_null'])){ $str_input->required(); }
                    if(isset($field['description'])){ $str_input->help($field['description']); }
                    
                    $rules = $field['rules'];
                    if(isset($rules['preg'])){ $str_input->pattern($rules['preg']); }
                        if(isset($rules['min_length_in_byte'])){ $form_rule.='min:'.(int)$rules['min_length_in_byte'];}
                        if(isset($rules['max_length_in_byte'])){ $form_rule.='max:'.(int)$rules['max_length_in_byte'];}
                    if($form_rule){ $str_input->rules($form_rule);}
                    if(isset($rules['reference'])){
                        $a = explode(' ' , $rules['reference']);
                        $datas = array_combine($a , $a);
                        $str_input->datalist($datas);
                    }
                    if(isset($field['default'])){ $str_input->default($field['default']); }

                    
                    
                    break;
                case 'selector':
                    unset($default_value);
                    unset($options);
                    foreach ($field['values'] as $option) {
                            if($option['selected']){
                                if($field['is_multi']){
                                    $default_value[] = $option['value'];
                                }else{
                                    $default_value = $option['value'];
                                }
                            }
                            $options[$option['value']] = $option['title'];
                        }
                    if(!$field['is_multi']){
                        if($field['style'] == 'select'){
                            $input = $form->select($form_key ,$field['name'])
                                ->options($options);
                        }else{
                            $input = $form->radio($form_key ,$field['name'])->required()
                                ->options($options);
                            
                        }
                        if(isset($field['description'])){ $input->help($field['description']); }

                    }else{
                        if($field['style'] == 'select'){
                            $input = $form->multipleSelect($form_key ,$field['name'])->required()
                                ->options($options);
                        }else{
                            $input = $form->checkbox($form_key ,$field['name'])
                                ->options($options);
                        }

                        if(isset($field['description'])){ $input->help($field['description']); }
                        if(!is_null($default_value)){ 
                            $input->default($default_value);
                        }

                    }
                    break;
                case 'object':
                    if(!$in_object){
                        $form->divider($field['name']);
                        $this->_form_fields($form , $field['elements'] , true , $key.'.');
                    }else{
                        throw new \Exception("不支持多层object嵌套", 1);
                        
                    }                    
                    break;
                case 'object_list':
                    if(!$in_object){
                        if(count($field['elements'])>4){
                            $table_width = count($field['elements'])*200;
                            Admin::script('
                                $("#has-many-'.$key.'").css("overflow" , "scroll")
                                $("#has-many-'.$key.'").css("width" , "'.$table_width.'px")
                                $("#has-many-'.$key.'").parent().css("overflow" , "scroll")
                            ');
                        }

                        $form->table($key , $field['name'],function ($table) use ($field , $key) {
                            $this->_form_fields($table , $field['elements'] , true );
                        });
                    }else{
                        throw new \Exception("不支持多层object嵌套", 1);
                    }
                    
                    break;
                default:
                    # code...
                    break;
            }
        }

    }

    public function check_conf(Content $content, Request $request ,$project_code){
        $this->_read_metaconf_check_permission($project_code);

        try {
            $conf_data = $this->_read_fields_input($request , $this->metaconf_json['fields']);    
        } catch (\Exception $e) {
            die($e->getMessage());
        }
        die("1");
    }
    
    // save保存配置数据接口
    public function save_conf(Content $content, Request $request ,$project_code, $version_id){
        $this->_read_metaconf_check_permission($project_code);
        $op_log = $request->input('op_log');

        try {
            // 获取old_data
            $mysqlData = ConfManagerMysql::getDataByWhere(['value'], [
                'project_code' => $project_code,
                'version_id' => $version_id,
            ]);
            $old_data = !empty($mysqlData) ? $mysqlData['value'] : '';

            $conf_data_input = $this->_read_fields_input($request, $this->metaconf_json['fields']);

            $conf_data = json_encode($conf_data_input);
            if (strpos($project_code, ":") !== false) {
                $projectTypeArr = explode(":", $project_code);
            } else {
                $projectTypeArr = explode("_", $project_code);
            }
            $data = [
                'project_type' => $projectTypeArr[0],
                'project_name' => $this->metaconf_json['project_name'],
                'value' => json_encode($conf_data_input, JSON_UNESCAPED_UNICODE),
                'update_username' => Admin::user()->username,
                'updated_at' => date('Y-m-d H:i:s', time()),
                'status' => 1,
            ];
            $dataWhere = [
                'project_code' => $project_code,
                'version_id' => $version_id,
            ];

            $updateMysql = ConfManagerMysql::updateData(array_merge($data, $dataWhere), $dataWhere);
            if ($updateMysql == 0) {
                throw new \Exception("更新mysql配置失败", 1);
            }

            // 通知conf-go进行同步
            $result = Curl::Request('POST', HhzEnv::configDomain() . 'confNotify');
            if ($result['json']['code'] != 1) {
                throw new \Exception("同步到conf-go失败" . HhzEnv::configDomain(), 1);
            }

            //记录变更日志
            ConfManagerLogMysql::insertData([
                'admin_id' => Admin::user()->id,
                'op_action' => ConfManagerLogMysql::ACT_UPDATE_VERSION_DATA,
                'version_id' => $version_id,
                'project_code' => $project_code,
                'old_data' => $old_data,
                'new_data' => $conf_data,
                'op_log' => $op_log
            ]);
        } catch (\Exception $e) {
            admin_toastr($e->getMessage(), 'error', ['timeOut' => 5000]);
            return redirect('/admin/confManager/'.$project_code. '/' . $version_id .'/edit_conf/')->with(compact('success'));
        }

        admin_toastr('保存成功', 'success', ['timeOut' => 5000]);
        return redirect('/admin/confManager/'.$project_code. '/' . $version_id . '/edit_conf/')->with(compact('success'));
    }

    // save保存配置时读取输入数据
    private function _read_fields_input($request , $fields , $key_prefix = ''){        
        foreach ($fields as $key => $field) {
            
            $request_key = $key_prefix.$key;
            switch ($field['type']) {
                case 'bool':
                    $conf_data[$key] = $request->input($request_key , $field['default']);
                    $conf_data[$key] = $conf_data[$key] == 'on' ? 1 : 0;
                    break;
                case 'int':
                    $conf_data[$key] = $request->input($request_key , $field['default']);
                    if(isset($field['rules']['max']) && $conf_data[$key] > $field['rules']['max'])
                        throw new \Exception($field['name'] . " ".$conf_data[$key]." 大于最大值限制 :".$field['rules']['max'], 1);
                    if(isset($field['rules']['min']) && $conf_data[$key] < $field['rules']['min'])
                        throw new \Exception($field['name'] . " ".$conf_data[$key]." 小于最小值限制 :".$field['rules']['in'], 1);
                    break;
                case 'date':
                case 'datetime':
                case 'color':
                    $conf_data[$key] = $request->input($request_key , $field['default']);
                    break;
                case 'pic_upload':
                    $conf_data[$key] = $request->input($request_key);
                    $conf_data[$key.'_url'] = ImgUrl::getUrl(ImgUrl::APPTYPE_OP , $request->input($request_key) , ImgUrl::IMAGE_SIZE_OP_ORI);
                    break;
                case 'hhzlink':
                    // $tmp = $request->input($key);
                    
                    $conf_data[$key]['link_type'] = $request->input($key.'.link_type');
                    $conf_data[$key]['link_params'] = $request->input($key.'.link_params');

                    break;
                case 'string':
                    $conf_data[$key] = $request->input($request_key , $field['default']);
                    if(isset($field['rules']['preg']) && !preg_match('/'.$field['rules']['preg'].'/' , $conf_data[$key]))
                        throw new \Exception($field['name'] .'不符合正则规则：'.$field['rules']['preg'], 1);
                    if(isset($field['rules']['max_length_in_byte']) && strlen($conf_data[$key]) > $field['rules']['max_length_in_byte'])
                        throw new \Exception($field['name'] .'超过字节长度：'.$field['rules']['min_length_in_byte'], 1);
                    if(isset($field['rules']['min_length_in_byte']) && strlen($conf_data[$key]) < $field['rules']['min_length_in_byte'])
                        throw new \Exception($field['name'] .'未达到字节长度：'.$field['rules']['min_length_in_byte'], 1);
                    if(isset($field['rules']['max_width_in_cn']) && mb_strwidth($conf_data[$key]) > $field['rules']['max_width_in_cn'])
                        throw new \Exception($field['name'] .'超过中文宽度：'.$field['rules']['min_length_in_byte'], 1);
                    if(isset($field['rules']['min_width_in_cn']) && mb_strwidth($conf_data[$key]) < $field['rules']['min_width_in_cn'])
                        throw new \Exception($field['name'] .'未达到中文宽度：'.$field['rules']['min_length_in_byte'], 1);
                    break;
                case 'selector':
                    $conf_data[$key] = $request->input($request_key , $field['default']);
                    $all_values = array_column($field['values'], 'value');
                    #单选
                    if($field['is_multi'] == false){
                        if(!in_array($conf_data[$key] , $all_values))
                            throw new \Exception($field['name'] .'不在备选范围之内', 1);
                    }else{ #多选
                        $conf_data[$key] = array_filter($conf_data[$key]);
                        if(!is_array($conf_data[$key]))
                            throw new \Exception($field['name'] .'值不是数组', 1);
                        #去除空值
                        $conf_data[$key] = array_filter($conf_data[$key]);
                        if(empty($conf_data[$key]))
                            throw new \Exception($field['name']."值不能为空", 1);
                        if(count(array_unique($conf_data[$key])) != count($conf_data[$key]))
                            throw new \Exception($field['name'].'有重复的值', 1);
                        if(array_intersect($conf_data[$key] , $all_values) != $conf_data[$key])
                            throw new \Exception($field['name'] .'值 不在备选范围之内', 1);
                        if(isset($field['rules']['max_selected']) && count($conf_data[$key]) > $field['rules']['max_selected'])
                            throw new \Exception($field['name'] .'值 最多选择 '.$field['rules']['max_selected'].' 项', 1);
                    }
                    break; 
                case 'object':
                    
                    $conf_data[$key] = $this->_read_fields_input($request , $field['elements'] , $key.'.');
                    break;
                case 'object_list':

                    $obj_list = $request->input($request_key);
                    if(empty($obj_list)){

                        throw new \Exception($field['name']." empty", 1);
                    }else{
                        $ks = array_keys($obj_list);
                        foreach ($ks as $k) {
                            if($obj_list[$k]['_remove_']!=1){
                            $conf_data[$key][] = $this->_read_fields_input($request , $field['elements'] , $key.'.'.$k.'.');
                            }
                        }
                    }

                default:
                    # code...
                    break;
            }
            
        }

        return $conf_data;
    }

    //删除版本确认页面
    public function del_version_confirm(Content $content, Request $request ,$project_code, $version_id){
        if($project_code){
            $this->_read_metaconf_check_permission($project_code);
        }

        $conf_info = ConfManagerMysql::getDataByWhere(['version_name'],
            ['project_code' => $project_code, 'version_id' => $version_id]);

        $form = new Form($this->metaconf);
        $form->textarea('op_log' , '变更日志')->rows(3)->placeholder('为什么要进行本次变更？')->required();

        $form->action('/admin/confManager/'.$project_code.'/'.$version_id.'/del_version');

        $box = new Box('确认删除['.$conf_info['version_name'].']版本？', $form->render());
        $content->row($box);
        return $content
            ->header('配置管理')
            ->breadcrumb(['text' => '配置管理']);
    }

    //删除版本接口
    public function del_version(Content $content, Request $request ,$project_code, $version_id){
        $this->_read_metaconf_check_permission($project_code);
        if($version_id == 'default'){
            die('can not del default version');
        }

        $op_log = $request->input('op_log');

        $conf = ConfManagerMysql::getDataByWhere(['id', 'version_detail'],
            ['project_code' => $project_code, 'version_id' => $version_id]);

        if(!$conf){
            die('没有这个版本');
        }else{
            try {

                // 操作config_set
                ConfManagerMysql::updateData([
                    'status' => 2,
                    'deleted_time' => time(),
                    'delete_username' => Admin::user()->username,
                ], [
                    'project_code' => $project_code, 'version_id' => $version_id
                ]);

                // 通知conf-go进行同步
                $result = Curl::Request('POST', HhzEnv::configDomain() . 'confNotify');
                if ($result['json']['code'] != 1) {
                    throw new \Exception("同步到conf-go失败" . HhzEnv::configDomain(), 1);
                }

            } catch (\Exception $e) {
                die('etcd 删除失败');
            }
        }

        //记录变更日志
        ConfManagerLogMysql::insertData([
            'admin_id' => Admin::user()->id,
            'op_action' => ConfManagerLogMysql::ACT_DELETE_VERSION,
            'project_code' => $project_code,
            'version_id'=>$version_id,
            'old_data' => $conf['version_detail'],
            'new_data' => '',
            'op_log' => $op_log
        ]);

        admin_toastr('删除成功', 'success', ['timeOut' => 6000]);
        return redirect('/admin/confManager/'.$project_code.'/1/edit_conf/')->with(compact('success'));
    }
}